/***************************************************************************\
 * The Mattise Kernel														*
 * Copyright 2007 Matthew Iselin											*
 * Licensed under the GPL													*
 *																			*
 * idt.cc																	*
 *																			*
 * Sets up the IDT for Mattise.												*
 *																			*
\***************************************************************************/

#include <system.h>
#include <memory.h>
#include <paging.h>

/// An IDT entry
struct idt_entry
{
    unsigned short base_lo;
    unsigned short sel;        /* Our kernel segment goes here! */
    unsigned char always0;     /* This will ALWAYS be set to 0! */
    unsigned char flags;       /* Set using the above table! */
    unsigned short base_hi;
} __attribute__((packed));

/// IDT pointer, for loading into the IDTR
struct idt_ptr
{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));

/// 256 entry IDT
struct idt_entry idt[256];

extern "C" {

/// The IDT pointer - loaded into the IDTR
struct idt_ptr idtp;

/// Loads the IDT pointer
extern void idt_load();

};

/// Sets an entry in the IDT
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
{
	// install it
	idt[num].base_lo = (base & 0xFFFF);
	idt[num].sel = sel;
	idt[num].always0 = 0;
	idt[num].flags = flags;
	idt[num].base_hi = (base >> 16) & 0xFFFF;
}

/// Installs the IDT - interrupts _must_ be disabled first
void idt_install()
{
	// Sets the special IDT pointer up
	idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
	idtp.base = (unsigned int) &idt;

	// Clear out the entire IDT, initializing it to zeros
	// This is why interrupts must be disabled
	memset(&idt, 0, sizeof(struct idt_entry) * 256);
	
	// map as USER - otherwise we GPF in ring3
	MapPhysicalAddress( 0x9C000, idtp.base, idtp.base, PF_PRESENT | PF_READWRITE | PF_USER );

	// Points the processor's internal register to the new IDT
	idt_load();
}
